package view
{
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;

    import view.ImageLocator;

    public class Cell extends Sprite
    {
        public static var WIDTH:Number = 34;
        public static var HEIGHT:Number = 40;
        public static var LOCKED_ALL:Boolean = false;
        public static var SWAPPING:Boolean = false;
        public static var SELECTED_CELL:Cell = null;
        public static var OVERED_CELL:Cell = null;
        public static var STATE_NORMAL:int = 0;
        public static var STATE_SELECTED:int = 1;
        public static var STATE_OVERED:int = 2;
        public static var STATE_MOVING:int = 3;
        public static var TYPE_NUM:int = 4;
        public static var TYPE_EMPTY:int = -1;
        public static var COLORS:Array = new Array(0xFF0000, 0xFFFF00,
                                                   0x00C0FF, 0x00FF00,
                                                   0xFF30A0, 0xA030FF);
        public static var eventDispatcher:EventDispatcher = new EventDispatcher();
        public static var CELL_MOVED:String = "CELL_MOVED";
        public static var CELL_ERASED:String = "CELL_ERASED";

        public var col:int;
        public var row:int;
        public var posX:Number;
        public var posY:Number;
        public var state:int;
        public var type:int;
        public var erased:Boolean;

        private var swapType:int;
        private var swapX:Number;
        private var swapY:Number;
        private var img:Bitmap;
        private var hitA:Sprite;

        public function Cell(t:int, col:int, row:int, x:Number, y:Number)
        {
            this.state = Cell.STATE_NORMAL;
            this.type = t;
            this.hitA = new Sprite();
            this.hitA.graphics.clear();
            this.hitA.graphics.beginFill(0, 0);
            this.hitA.graphics.moveTo(Cell.WIDTH/2, Cell.HEIGHT/4);
            this.hitA.graphics.lineTo(0, Cell.HEIGHT/2);
            this.hitA.graphics.lineTo(-Cell.WIDTH/2, Cell.HEIGHT/4);
            this.hitA.graphics.lineTo(-Cell.WIDTH/2, -Cell.HEIGHT/4);
            this.hitA.graphics.lineTo(0, -Cell.HEIGHT/2);
            this.hitA.graphics.lineTo(Cell.WIDTH/2, -Cell.HEIGHT/4);
            this.hitA.graphics.endFill();
            this.hitArea = this.hitA;
            this.addChild(hitA);

            this.erased = false;
            this.buttonMode = true;
            this.col = col;
            this.row = row;
            this.x = x;
            this.y = y;
            this.posX = x;
            this.posY = y;
            this.addEventListener(MouseEvent.MOUSE_OVER, this.mouseOver);
            this.addEventListener(MouseEvent.MOUSE_OUT, this.mouseOut);
            this.addEventListener(MouseEvent.MOUSE_DOWN, this.mouseDown);
        }

        public function reset():void
        {
            this.state = Cell.STATE_NORMAL;
        }

// MoveFunction
        public static function addMovedListener(m:String, listener:Function):void
        {
            Cell.eventDispatcher.addEventListener(m, listener);
        }

        public static function removeMovedListener(m:String, listener:Function):void
        {
            Cell.eventDispatcher.removeEventListener(m, listener);
        }

        public function eraseded():void
        {
            this.removeEventListener(Event.ENTER_FRAME, this.erasing);
            this.type = TYPE_EMPTY;
            this.scaleX = 1;
            this.erased = false;
            this.display();
            var event:Event = new Event(Cell.CELL_ERASED);
            Cell.eventDispatcher.dispatchEvent(event);
        }

        public function erase():void
        {
            this.addEventListener(Event.ENTER_FRAME, this.erasing);
        }

        public function erasing(e:Event):void
        {
            if(this.scaleX-0.25 > 0)
            {
                this.scaleX -= 0.25;
            }
            else
            {
                this.eraseded();
            }
        }

        public function moved():void
        {
            this.removeEventListener(Event.ENTER_FRAME, this.moving);
            this.state = Cell.STATE_NORMAL;
            this.type = this.swapType;
            this.x = this.posX;
            this.y = this.posY;
            this.display();
            var event:Event = new Event(Cell.CELL_MOVED);
            Cell.eventDispatcher.dispatchEvent(event);
        }

        public function moveTo(cell:Cell):void
        {
            this.state = Cell.STATE_MOVING;
            this.swapType = cell.type;
            this.swapX = cell.posX;
            this.swapY = cell.posY;
            this.addEventListener(Event.ENTER_FRAME, this.moving);
        }

        private function moving(e:Event):void
        {
            var dx:Number = swapX - this.posX;
            var dy:Number = swapY - this.posY;
            var l:Number = Math.sqrt(dx*dx + dy*dy);
            var v:Number = 18;
            if(Cell.SWAPPING)
            {
                v = 6;
            }
            this.x += v*dx/l;
            this.y += v*dy/l;
            if((this.posX - this.x)*(swapX - this.x) +
               (this.posY - this.y)*(swapY - this.y) > 0)
            {
                this.x = swapX;
                this.y = swapY;
                this.moved();
            }
        }

// Display
        public function display():void
        {
            if(this.img != null)
            {
                removeChild(this.img);
                this.img = null;
            }
            switch(type)
            {
                case -1:
                    this.img = new ImageLocator.cellE();
                    break;
                case 0:
                    this.img = new ImageLocator.cell0();
                    break;
                case 1:
                    this.img = new ImageLocator.cell1();
                    break;
                case 2:
                    this.img = new ImageLocator.cell2();
                    break;
                case 3:
                    this.img = new ImageLocator.cell3();
                    break;
                case 4:
                    this.img = new ImageLocator.cell4();
                    break;
                case 5:
                    this.img = new ImageLocator.cell5();
                    break;
                default:
                    break;
            }
            if(this.img != null)
            {
                this.img.x = -17;
                this.img.y = -20;
                this.addChild(this.img);
            }
            /*
            var color:uint = Cell.COLORS[type];
            var alpha:Number = 1;

            this.graphics.clear();
            if(this.state == Cell.STATE_NORMAL)
            {
                this.graphics.lineStyle(1, 0x303030, 1);
                alpha = 0.75;
            }
            else if(this.state == Cell.STATE_SELECTED)
            {
                this.graphics.lineStyle(2, 0x0000FF, 0.75);
            }
            else if(this.state == Cell.STATE_OVERED)
            {
                this.graphics.lineStyle(8, color, 0.3);
            }

            if(this.type == Cell.TYPE_EMPTY)
            {
                this.graphics.beginFill(0x000000, 0);
            }
            else
            {
                var colors:Array = [0xFFFFFF, color];
                var alphas:Array = [1, alpha];
                var ratios:Array = [0, 190];
                var matr:Matrix = new Matrix();
                matr.createGradientBox(17, 20, 10.1, -1, 0);
                this.graphics.beginGradientFill(GradientType.LINEAR,
                                                colors, alphas,
                                                ratios, matr,
                                                SpreadMethod.REFLECT,
                                                InterpolationMethod.RGB, 0.75);
            }
            this.graphics.moveTo(Cell.WIDTH/2, Cell.HEIGHT/4);
            this.graphics.lineTo(0, Cell.HEIGHT/2);
            this.graphics.lineTo(-Cell.WIDTH/2, Cell.HEIGHT/4);
            this.graphics.lineTo(-Cell.WIDTH/2, -Cell.HEIGHT/4);
            this.graphics.lineTo(0, -Cell.HEIGHT/2);
            this.graphics.lineTo(Cell.WIDTH/2, -Cell.HEIGHT/4);
            this.graphics.endFill();*/
        }

// MouseFunction
        private function mouseOut(e:MouseEvent):void
        {
            this.alpha = 1;
        }

        private function mouseOver(e:MouseEvent):void
        {
            if(!Cell.LOCKED_ALL)
            {
                if(this.type != Cell.TYPE_EMPTY && Cell.SELECTED_CELL != this)
                {
                    Cell.OVERED_CELL = this;
                    this.state = Cell.STATE_OVERED;
                    //this.display();
                    this.alpha = 0.6;
                }
            }
        }

        private function mouseDown(e:MouseEvent):void
        {
            if(!Cell.LOCKED_ALL)
            {
                if(this.type != Cell.TYPE_EMPTY)
                {
                    if(Cell.SELECTED_CELL != null)
                    {
                        Cell.SELECTED_CELL.state = Cell.STATE_NORMAL;
                        Cell.SELECTED_CELL.display();
                    }
                    if(Cell.SELECTED_CELL != this)
                    {
                        Cell.SELECTED_CELL = this;
                        this.state = Cell.STATE_SELECTED;
                        //this.display();
                    }
                    else
                    {
                        Cell.SELECTED_CELL = null;
                        this.state = Cell.STATE_OVERED;
                        //this.display();
                    }
                }
            }
        }
    }
}
